package com.lcp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lcp.entity.ExerciseRecord;
import com.lcp.mapper.ExerciseRecordMapper;
import com.lcp.service.ExerciseRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ExerciseRecordServiceImpl implements ExerciseRecordService {

    @Autowired
    private ExerciseRecordMapper exerciseRecordMapper;

    @Override
    public ExerciseRecord getById(Long id) {
        return exerciseRecordMapper.selectById(id);
    }

    @Override
    public List<ExerciseRecord> listByUserId(Long userId) {
        return exerciseRecordMapper.selectList(
            new QueryWrapper<ExerciseRecord>()
                .eq("user_id", userId)
                .orderByDesc("exercise_time")
        );
    }

    @Override
    public ExerciseRecord create(ExerciseRecord record) {
        record.setCreateTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        exerciseRecordMapper.insert(record);
        return record;
    }

    @Override
    public ExerciseRecord update(ExerciseRecord record) {
        record.setUpdateTime(LocalDateTime.now());
        exerciseRecordMapper.updateById(record);
        return record;
    }

    @Override
    public void delete(Long id) {
        exerciseRecordMapper.deleteById(id);
    }

    @Override
    public List<ExerciseRecord> listByDateRange(Long userId, String startDate, String endDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = LocalDateTime.parse(startDate + " 00:00:00", formatter);
        LocalDateTime end = LocalDateTime.parse(endDate + " 23:59:59", formatter);
        
        return exerciseRecordMapper.selectList(
            new QueryWrapper<ExerciseRecord>()
                .eq("user_id", userId)
                .between("exercise_time", start, end)
                .orderByDesc("exercise_time")
        );
    }

    @Override
    public List<ExerciseRecord> listByExerciseType(Long userId, String exerciseType, String date) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime start = LocalDateTime.parse(date + " 00:00:00", formatter);
        LocalDateTime end = LocalDateTime.parse(date + " 23:59:59", formatter);
        
        return exerciseRecordMapper.selectList(
            new QueryWrapper<ExerciseRecord>()
                .eq("user_id", userId)
                .eq("exercise_type", exerciseType)
                .between("exercise_time", start, end)
                .orderByAsc("exercise_time")
        );
    }

    @Override
    public Map<String, Object> getDailyExerciseSummary(Long userId, String date) {
        List<ExerciseRecord> records = listByDateRange(userId, date, date);
        
        Map<String, Object> summary = new HashMap<>();
        summary.put("totalDuration", records.stream()
            .mapToInt(ExerciseRecord::getDuration)
            .sum());
            
        summary.put("totalCalories", records.stream()
            .mapToInt(ExerciseRecord::getCalories)
            .sum());
            
        summary.put("exerciseCount", records.size());
        
        summary.put("exerciseTypes", records.stream()
            .collect(Collectors.groupingBy(
                ExerciseRecord::getExerciseType,
                Collectors.counting()
            )));
            
        summary.put("intensityDistribution", records.stream()
            .collect(Collectors.groupingBy(
                ExerciseRecord::getIntensity,
                Collectors.counting()
            )));
            
        return summary;
    }

    @Override
    public Map<String, Object> getWeeklyExerciseTrend(Long userId, String startDate, String endDate) {
        List<ExerciseRecord> records = listByDateRange(userId, startDate, endDate);
        
        Map<String, Object> trend = new HashMap<>();
        trend.put("dailyDuration", records.stream()
            .collect(Collectors.groupingBy(
                record -> record.getExerciseTime().toLocalDate().toString(),
                Collectors.summingInt(ExerciseRecord::getDuration)
            )));
            
        trend.put("dailyCalories", records.stream()
            .collect(Collectors.groupingBy(
                record -> record.getExerciseTime().toLocalDate().toString(),
                Collectors.summingInt(ExerciseRecord::getCalories)
            )));
            
        trend.put("exerciseTypeDistribution", records.stream()
            .collect(Collectors.groupingBy(
                ExerciseRecord::getExerciseType,
                Collectors.counting()
            )));
            
        return trend;
    }

    @Override
    public Map<String, Object> getExerciseStatistics(Long userId, String startDate, String endDate) {
        List<ExerciseRecord> records = listByDateRange(userId, startDate, endDate);
        
        Map<String, Object> statistics = new HashMap<>();
        
        // 计算总运动时长和卡路里消耗
        statistics.put("totalDuration", records.stream()
            .mapToInt(ExerciseRecord::getDuration)
            .sum());
        statistics.put("totalCalories", records.stream()
            .mapToInt(ExerciseRecord::getCalories)
            .sum());
            
        // 计算平均每次运动时长
        statistics.put("averageDuration", records.isEmpty() ? 0 :
            records.stream()
                .mapToInt(ExerciseRecord::getDuration)
                .average()
                .getAsDouble());
                
        // 计算最常进行的运动类型
        statistics.put("mostFrequentExercise", records.stream()
            .collect(Collectors.groupingBy(
                ExerciseRecord::getExerciseType,
                Collectors.counting()
            ))
            .entrySet()
            .stream()
            .max(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey)
            .orElse("无"));
            
        // 计算运动强度分布
        statistics.put("intensityDistribution", records.stream()
            .collect(Collectors.groupingBy(
                ExerciseRecord::getIntensity,
                Collectors.counting()
            )));
            
        return statistics;
    }
} 